package org.canaan.http.core.post;

import com.alibaba.fastjson.JSON;
import org.apache.http.Consts;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.canaan.http.HttpResponse;
import org.canaan.http.core.AbstractHttpClient;
import org.canaan.http.type.ParamType;
import org.canaan.http.urlpair.core.UrlPair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;

/**
 * post 请求
 * @author Canaan
 * @date 2017/8/9
 */
public class PostClient extends AbstractHttpClient <Object> {
    private final Logger logger = LoggerFactory.getLogger(PostClient.class);
    private final ParamType paramType;    //参数类型


    PostClient(PostHttpBuilder builder) {
        super(builder);
        this.paramType = builder.paramType;
    }

    @Override
    public HttpResponse execute(String url, Object param) throws IOException {

        HttpPost httpPost = null;
        try {
            // 创建http POST请求
             httpPost = new HttpPost(url);
            httpPost.setConfig(this.requestConfig);

            //设置请求头
            if (this.header != null && this.header.size() != 0) {
                for (String str : this.header.keySet()) {
                    httpPost.setHeader(str, header.get(str));
                }
            }
            //添加cookie
            if (this.cookies != null && this.cookies.size() != 0) {
                StringBuilder cookiesBuilder = new StringBuilder();
                for (String str : this.cookies.keySet()) {
                    cookiesBuilder.append(str).append("=").append(this.cookies.get(str)).append(";");
                }
                cookiesBuilder.deleteCharAt(cookiesBuilder.length() - 1);
                httpPost.setHeader("Cookie", cookiesBuilder.toString());
            }

            //设置参数
            if (param != null) {
                StringEntity stringEntity;
                switch (this.paramType) {
                    case FORM_URLENCODED:
                        // 将 参数解析成 key=value&key=value的字符串格式
                        ContentType contentType = ContentType.create("application/x-www-form-urlencoded", Consts.UTF_8);
                        String paramString = UrlPair.toURLPairString(param);
                        stringEntity = new StringEntity(paramString, contentType);
                        break;
                    case JSON:
                        if (!String.class.isInstance(param)) {
                            param = JSON.toJSONString(param);
                        }
                        stringEntity = new StringEntity(param.toString(), ContentType.APPLICATION_JSON);
                        break;
                    default:
                        stringEntity = new StringEntity(param.toString(), ContentType.DEFAULT_TEXT);
                }
                httpPost.setEntity(stringEntity);
            }

            //创建httpClient

            long begin = System.currentTimeMillis();
            response = httpClient.execute(httpPost);
            long end = System.currentTimeMillis();

            //获取 result 返回数据
            String responseData = "";
            if (response.getEntity() != null) {
                responseData =  EntityUtils.toString(response.getEntity(), "UTF-8");
            }

            HttpResponse _response = new HttpResponse(response);
            //发费时间计算
            _response.setSpendTime(end - begin);
            //cookies值
            if (cookieStore != null) {
                _response.setCookies(cookieStore.getCookies());
            } else {
                _response.setCookies(new ArrayList<Cookie>());
            }
            //返回数据
            _response.setData(responseData);
            //http状态
            _response.setHttpStatus(response.getStatusLine().getStatusCode());
            return _response;
        } finally {
            try {
                if(httpPost!=null){
                    httpPost.releaseConnection();
                    httpPost = null;
                }
            } catch (Exception e) {
                logger.error("",e);
            }
        }
    }


    public static PostHttpBuilder custom() {
        return new PostHttpBuilder();
    }

}
